package com.baizhi.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Configuration
@Aspect
public class CacheAop {
    @Autowired
    private RedisTemplate redisTemplate;
    private static Logger logger = LoggerFactory.getLogger(CacheAop.class);
    //前置增强，在执行写操作之前删除缓存
    @Before("@annotation(com.baizhi.annotation.DeleteCacheAnnotation)")
    public void deleteCache(JoinPoint joinPoint){
        //返回值为类名，这样就可以清除当前类对应的所有缓存
        String key = joinPoint.getTarget().getClass().getName();
        redisTemplate.delete(key);
    }
    @Around("@annotation(com.baizhi.annotation.AddCacheAnnotation)")
    public Object addCache(ProceedingJoinPoint joinPoint){
        //获取key 和 hashkey
        String key = joinPoint.getTarget().getClass().getName();
        String name = joinPoint.getSignature().getName();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(name);
        //拼接参数
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            stringBuilder.append(arg.toString());
        }
        String hashkey = stringBuilder.toString();
        //System.out.println("hashkey=="+hashkey);
        HashOperations hashOperations = redisTemplate.opsForHash();
        Object result = hashOperations.get(key, hashkey);
        //redis数据库没有数据就查询数据库
        if(result==null){
            logger.info("获取数据库数据");
            try {
                //方法放行执行数据库操作，
                result=joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            Map map = new HashMap();
            map.put(hashkey,result);
            System.out.println(hashkey);
            hashOperations.putAll(key,map);
            redisTemplate.expire(key,60, TimeUnit.SECONDS);
        }else {
            logger.info("获取缓存数据");
        }
        return result;
    }
}
